<?php

interface Component{
    public function operation();
}

class ConcreateComponent implements Component{
    public function operation(){
        echo 'I`m face!' . PHP_EOL;
    }
}

abstract class Decorator implements Component{
    protected $component;
    public function __construct(Component $component){
        $this->component = $component;
    }
}

class ConcreateDecoratorA extends Decorator{
    public $addedState = 1; //没什么实际意义的属性，只是区别于 ConcreateDecoratorB

    public function operation(){
        echo $this->component->operation() . ' Push ' . $this->addedState . ' cream!' . PHP_EOL;
    }
}
class ConcreateDecoratorB extends Decorator{
    public function operation(){
        $this->component->operation();
        $this->addedBehavior();
    }
    // 没什么实际意义的方法，只是区别于 ConcreateDecoratorA
    public function addedBehavior(){
        echo 'Push 2 cream!' . PHP_EOL;
    }
}

// 被装饰对象
// $component = new ConcreateComponent();
// $component->operation(); //I`m face!

// 装饰第一层
// $component = new ConcreateDecoratorA($component);
// $component->operation(); //I`m face! \n Push 1 cream!

// 装饰第二层
// $component = new ConcreateDecoratorB($component);
// $component->operation(); //I`m face! \n Push 1 cream! \n Push 2 cream!

// ... 不断被装饰

// 直接一次全部装饰完
// 请把上方的三个$component->operation();注释掉再看
$component2 = new ConcreateComponent(); // face
$component2 = new ConcreateDecoratorA($component2); // face 1
$component2 = new ConcreateDecoratorB($component2); // face 2
$component2->operation();